package math.arithmetic.elementray;

import math.arithmetic.elementray.operation.AbstractOperation;

import java.util.Arrays;

import static math.arithmetic.elementray.ResultFormater.COUNT_PER_LINE;
import static math.arithmetic.elementray.ResultFormater.LINE_PER_PAGE;

public class DeDuplicator {
    private final int lineDistance;
    private final AbstractOperation[] storedOps;
    private int curIndex = 0;
    private int totalOutput = 0;

    public DeDuplicator(int lineDistance) {
        this.lineDistance = lineDistance;
        this.storedOps = new AbstractOperation[COUNT_PER_LINE * lineDistance];
    }

    private int next(int index) {
        index += COUNT_PER_LINE;
        return index < storedOps.length ? index : index - storedOps.length;
    }

    public boolean isDuplicate(AbstractOperation equation) throws CloneNotSupportedException {
        if (totalOutput >= COUNT_PER_LINE * LINE_PER_PAGE) {
            curIndex = 0;
            totalOutput = 0;
            Arrays.fill(storedOps, null);
        }
        // The same line should not duplicate
        for (int i = this.curIndex % COUNT_PER_LINE; i > 0; i--) {
            if (storedOps[this.curIndex - i].equals(equation)) {
                return true;
            }
        }
        // The same column should not duplicate in "lineDistance" region
        int cur = this.curIndex;
        for (int i = 0; i < this.lineDistance; i++) {
            if (storedOps[cur] != null && storedOps[cur].equals(equation)) {
                return true;
            }
            cur = next(cur);
        }
        totalOutput++;
        storedOps[curIndex++] = equation.clone();
        if (curIndex >= storedOps.length) {
            curIndex = 0;
        }
        return false;
    }
}
